package com.ll3d.security;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author:linchong
 * @CreateTime:2020-07-15 23:56
 * @Description:处理token，加入到请求头中
 */
@Slf4j
@Component
public class SessionTokenFilter extends ZuulFilter {
	@Override
	public String filterType() {
		return "pre";
	}

	@Override
	public int filterOrder() {
		return 0;
	}

	@Override
	public boolean shouldFilter() {
		return true;
	}

	private RestTemplate restTemplate = new RestTemplate();

	/**
	 * session中将token拿到，加入到请求头中即可
	 * @return
	 * @throws ZuulException
	 */
	@Override
	public Object run() throws ZuulException {
		RequestContext requestContext = RequestContext.getCurrentContext();
		HttpServletRequest request = requestContext.getRequest();
		//针对api开头的请求，每次都会拦截下来，从session中拿出token,加入到请求头中

		log.info("token:{}",request.getSession().getAttribute("chong_token"));
		System.out.println(request.getSession().getAttribute("chong_token"));
		AccessToken token = (AccessToken) request.getSession().getAttribute("chong_token");
		if(token!=null){
			String tokenValue = token.getAccess_token();
			if(token.isExpired()){
				String oauthServiceUrl = "http://gateway.chong.com/9070/oken/oauth/token";
				HttpHeaders headers = new HttpHeaders();
				headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
				headers.setBasicAuth("admin","123456");

				MultiValueMap<String,String> params = new LinkedMultiValueMap<>();
				//刷新令牌
				params.add("refresh_token",token.getRefresh_token());
				//授权类型-刷新令牌
				params.add("grant_type","refresh_token");
				HttpEntity<MultiValueMap<String,String>> entity = new HttpEntity<>(params,headers);
				//刷新令牌的时候，可能refresh_token也过期了，这里进行处理，让用户重新走授权流程
				try{
					ResponseEntity<AccessToken> newToken = restTemplate.exchange(oauthServiceUrl, HttpMethod.POST, entity, AccessToken.class);
					request.getSession().setAttribute("chong_token",newToken.getBody());
					tokenValue = newToken.getBody().getAccess_token();
				}catch (Exception e){
					//报错，停止向下执行
					requestContext.setSendZuulResponse(false);
					requestContext.setResponseStatusCode(500);
					requestContext.setResponseBody("{\"message\":\"refresh fail\"}");
					requestContext.getResponse().setContentType("application/json");
				}

			}
			requestContext.addZuulRequestHeader("Authorization","bearer "+tokenValue);

		}
		return null;
	}
}














